﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using HPSocket;
using HPSocket.Tcp;

namespace Connection
{
    /// <summary>
    ///第三方SocketClient
    /// </summary>
    public class HpSocketClient
    {
        private readonly ITcpClient _client = new TcpClient();
        public CancellationTokenSource AnewReset = new CancellationTokenSource();

        /// <summary>
        /// 是否连接
        /// </summary>
        public bool IsConnection
        {
            get
            {
                if (!(_client == null))
                {
                    return _client.IsConnected;
                }
                else
                {
                    return false;
                }
            }
        }

        /// <summary>
        /// 连接委托
        /// </summary>
        public delegate void OnConnectDelegate();
        /// <summary>
        /// 连接事件
        /// </summary>
        public event OnConnectDelegate OnConnectThing;

        /// <summary>
        /// 目标连接在线委托
        /// </summary>
        /// <param name="TargetIp"></param>
        /// <param name="targetPort"></param>
        /// <param name="AddOrRemove"></param>
        public delegate void ConnectStateDelegate(string TargetIp, int targetPort, bool AddOrRemove);
        /// <summary>
        /// 目标连接在线事件
        /// </summary>
        public event ConnectStateDelegate SocketConnOline;

        /// <summary>
        /// 接收目标数据委托
        /// </summary>
        /// <param name="TargetIp"></param>
        /// <param name="targetPort"></param>
        /// <param name="data"></param>
        public delegate void OnReceiveMessageDelegate(string TargetIp, int targetPort, byte[] data);
        /// <summary>
        /// 接收目标数据事件
        /// </summary>
        public event OnReceiveMessageDelegate OnReceiveMessage;


        /// <summary>
        /// 初始化Client
        /// </summary>
        /// <param name="TargetIp">目的IP</param>
        /// <param name="targetPort">目的端口</param>
        /// <param name="BindIp">本地IP</param>
        /// <param name="BindPort">本地端口</param>
        public HpSocketClient(string TargetIp, int targetPort, string BindIp = null, int BindPort = 0)
        {
            // 缓冲区大小
            _client.SocketBufferSize = 4096; // 4K
            // 异步连接
            _client.Async = true;
            _client.Address = TargetIp;
            _client.Port = (ushort)targetPort;
            if (!(BindIp == null) && !(BindIp == ""))
            {
                _client.BindAddress = BindIp;
            }
            if (!(BindPort == 0))
            {
                _client.BindPort = (ushort)BindPort;
            }
            // 事件绑定
            _client.OnPrepareConnect += OnPrepareConnect;//准备连接事件
            _client.OnConnect += OnConnect;//连接事件
            // ssl client 还应该绑定握手事件, 该事件到达说明两端握手成功, OnConnect只能说明连接成功了, 还没握手
            _client.OnHandShake += OnHandShake;//握手事件
            _client.OnReceive += OnReceive;//接收数据事件
            _client.OnClose += OnClose;//断开事件
        }

        /// <summary>
        /// 准备连接响应
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="socket"></param>
        /// <returns></returns>
        private HandleResult OnPrepareConnect(IClient sender, IntPtr socket)
        {
            string a = sender.Address;
            string b = sender.Port.ToString();
            string c = socket.ToString();
            string d = sender.Version;

            return HandleResult.Ok;
        }

        /// <summary>
        /// 连接响应
        /// </summary>
        /// <param name="sender"></param>
        /// <returns></returns>
        private HandleResult OnConnect(IClient sender)
        {
            string a = sender.Address;
            string b = sender.Port.ToString();
            try
            {
                if (!(SocketConnOline == null))
                {
                    SocketConnOline(sender.Address, sender.Port, true);
                }

            }
            catch (Exception)
            {

            }
            return HandleResult.Ok;
        }

        /// <summary>
        /// 握手响应
        /// </summary>
        /// <param name="sender"></param>
        /// <returns></returns>
        private HandleResult OnHandShake(IClient sender)
        {
            string a = sender.Address;
            string b = sender.Port.ToString();
            return HandleResult.Ok;
        }

        /// <summary>
        /// 接收数据响应
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        private HandleResult OnReceive(IClient sender, byte[] data)
        {
            string a = sender.Address;
            string b = sender.Port.ToString();
            string c = Encoding.GetEncoding("gb18030").GetString(data);
            try
            {
                OnReceiveMessage(sender.Address, sender.Port, data);
            }
            catch (Exception ex)
            {

            }
            return HandleResult.Ok;
        }

        /// <summary>
        /// 断开响应
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="socketOperation"></param>
        /// <param name="errorCode"></param>
        /// <returns></returns>
        private HandleResult OnClose(IClient sender, SocketOperation socketOperation, int errorCode)
        {
            try
            {
                if (!(SocketConnOline == null))
                {
                    SocketConnOline(sender.Address, sender.Port, false);
                }

            }
            catch (Exception)
            {
            }
            return HandleResult.Ok;
        }



        /// <summary>
        /// 开启服务
        /// </summary>
        /// <returns></returns>
        public bool Start()
        {
            try
            {
                _client.Connect();
            }
            catch (Exception)
            {

                return false;
            }
            return true;
        }

        /// <summary>
        /// 关闭服务
        /// </summary>
        /// <returns></returns>
        public bool Close()
        {
            AnewReset.Cancel();
            return _client.Stop();
        }

        /// <summary>
        /// 资源释放
        /// </summary>
        /// <returns></returns>
        public bool Dispose()
        {
            AnewReset.Cancel();
            _client.Dispose();
            return true;
        }

        /// <summary>
        /// 是否连接正常状态
        /// </summary>
        /// <returns></returns>
        //public bool IsConnection()
        //{
        //    return _client.IsConnected;
        //}

        /// <summary>
        /// 发送数据string
        /// </summary>
        /// <param name="Data">数据</param>
        /// <returns></returns>
        public bool SendData(string Data)
        {
            byte[] DataByte = Encoding.GetEncoding("gb18030").GetBytes(Data);
            return _client.Send(DataByte, DataByte.Length);
        }
    }
}
